from pylons import request
from pylons import session
from webob.exc import HTTPNotFound, HTTPUnauthorized, HTTPForbidden

import logging
log = logging.getLogger(__name__)

def check_authentication():
    #~ return False
    #~ return True
    #~ session = request.environ['beaker.session']
    if session.has_key('authority.user'):
        log.debug('authority.user found in session')
        user = session['authority.user']
        log.debug('username = %s' % user.name)
        if user.name != 'anonymous':
            log.debug('authentication succeeded')
            return True
            
    return False

'''
class interceptor(object):
    def __init__(self, before, after):
        self.before = before
        self.after = after
    def __call__(self, f):
        def wrapper(*args, **kwargs):
            stdout.write(self.before)
            f(*args, **kwargs)
            stdout.write(self.after)
        return wrapper
        
'''

class require2(object):
    def __init__(self, condition=None): #, env=request.environ):
        '''Initialize the require decorator class
        
        condition - an instance of the AuthorityCondition class
        '''
        self.condition = condition
        
    def check_authentication(self, user):
        if user:
            if user.name != 'anonymous':
                log.debug('authentication succeeded')
                return True
        return False
        
    def check_authorization(self, user):
        if self.condition:
            if user:
                return self.condition(user)
            #if no user then return false
            return False
        # if no condition, then return true
        return True

    def __call__(self, func):
        def wrapper(*__args,**__kw):
            log.debug("entering " + func.__name__)
            log.debug('*__args = ' + str(__args))
            log.debug('**__kw = ' + str(__kw))

            if session.has_key('authority.user'):
                log.debug('authority.user found in session')
                user = session['authority.user']
                log.debug('username = %s' % user.name)

            if not self.check_authentication(user):
                log.debug('user not authenticated...')
                log.debug(str(dir(HTTPUnauthorized('Not allowed').exception)))
                raise HTTPUnauthorized('Not allowed').exception

            if not self.check_authorization(user):
                log.debug('user not authorized')
                raise HTTPForbidden().exception

            try:
                return func(*__args,**__kw)
            finally:
                log.debug("exiting " + func.__name__)
        return wrapper

def require(func):
    '''
    - decorator checks to see if user is authenticated
    - if not, raise 401
    - if so, proceed
        - decorator checks to see if user is authorized
            - if not, raise 403
            - if so, proceed
    '''
    def wrapper(*__args,**__kw):
        log.debug("entering " + func.__name__)
        log.debug('*__args = ' + str(__args))
        log.debug('**__kw = ' + str(__kw))
        if check_authentication():
            try:
                return func(*__args,**__kw)
            finally:
                log.debug("exiting " + func.__name__)
        else:
            log.debug(str(dir(HTTPUnauthorized('Not allowed').exception)))
            raise HTTPUnauthorized('Not allowed').exception
            
    return wrapper
